package com.ld.service;

import com.ld.dao.StoreDao;
import com.ld.entity.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("storeService")
@Transactional
public class StoreServiceImpl implements StoreService {

    @Resource(name = "storeDao")
    private StoreDao storeDao;


    /**
     * @param filmId 传入电影id,返回所有拥有此影片的店铺id
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public List<Integer> getFilmOwnerStoreId(Integer filmId) {
        return storeDao.getFilmOwnerStoreId(filmId);
    }


    /**
     * @param filmId  电影id
     * @param storeId 店铺id
     * @return 这部电影在这家店 真实库存 = 原本库存 -尚未归还数量
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Integer getCurrentFilmCount(Integer filmId, Integer storeId) {
        Integer originalCount = storeDao.getFilmCount(filmId, storeId);//原本库存
        Integer unreturnedCount = storeDao.getUnreturnedCount(filmId, storeId);//尚未归还数量
        return originalCount - unreturnedCount;
    }

    /**
     * @param filmId 传入电影id
     * @return 有则返回店铺信息list<Store> 无则返回null
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public List<Store> getStoreCurrentFilmCount(Integer filmId) {
        //调用本类的方法,返回所有拥有此影片的店铺id
        List<Integer> storeIds = getFilmOwnerStoreId(filmId);
        if (storeIds != null && storeIds.size() > 0) {
            //传入店铺id集合,返回查询店铺的详细地址
            List<Store> storeInfo = storeDao.getStoreInfo(storeIds);
            for (Store store : storeInfo) {
                store.setFilmCount(getCurrentFilmCount(filmId, store.getStoreId()));
            }
            return storeInfo;
        }
        return null;
    }


    /**
     * @param storeId     店铺id
     * @param currentPage 当前页
     * @param pageSize    每页大小
     * @return 这家店所有尚未归还的信息(包括分页信息)
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Map<String, Object> getAllUnreturnedInfo(Integer storeId,
                                                    Integer currentPage,
                                                    Integer pageSize) {
        Integer allUnreturnedCount = storeDao.getAllUnreturnedCount(storeId);
        PageInfo pageInfo = new PageInfo();
        pageInfo.setTotalCount(allUnreturnedCount);
        pageInfo.setCurrentPage(currentPage - 1);//mysql从0开始
        pageInfo.setPageSize(pageSize);
        List<Rental> allUnreturnedInfo = storeDao.getAllUnreturnedInfo(storeId, (currentPage-1)*pageSize, pageSize);
        Map<String, Object> allUnreturnedInfoMap = new HashMap<>();
        allUnreturnedInfoMap.put("pageInfo", pageInfo);
        allUnreturnedInfoMap.put("allUnreturnedInfo", allUnreturnedInfo);
        return allUnreturnedInfoMap;
    }


    /**
     * 结算
     *
     * @param rental 同时update rental表 和 insert payment表
     * @return 提示信息
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public String clearing(Rental rental) {
        String returnDateIs = storeDao.returnDateIsNull(rental.getRentalId());
        if (returnDateIs == null || "".equals(returnDateIs)) {
            Integer rentalDone = storeDao.clearingUpdateRental(rental);
            Integer paymentDone = storeDao.clearingInsertPayment(rental);
            if (rentalDone == 1 && paymentDone == 1) {
                return "付款成功";
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return "付款失败";
        }
        return "已经结算,勿重复提交";
    }


    /**
     * @param storeId       只能查询自家店的东西
     * @param searchType    查询类型 按电影名,按电影编号,按电影类型,按电影等级,按演员名称
     * @param searchContent 搜索内容
     * @return 返回查询结果
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Map<String, Object> searchByType(Integer storeId, String searchType, String searchContent) {
        Map<String, Object> resultMap = new HashMap<>();

        switch (searchType) {
            case "byFilmTitle":
                break;
            case "byFilmId":

                break;
            case "byFilmType":

                break;
            case "byFilmRating":

                break;
            case "byActorName":
                List<Actor> fuzzyActors = storeDao.searchByActorName(searchContent);
                resultMap.put(searchType, fuzzyActors);
                break;
            default://错误
                resultMap = null;
                break;
        }
        return resultMap;
    }

    /**
     * 根据演员id查询这个演员所参与的电影,只能查询自己店铺的电影
     *
     * @param actorId 演员id
     * @param storeId 店铺id
     * @return film中的film_id, title, rating, category, inventory_id, isRental
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public List<Film> getWhichFilmTheActorWereInvolvedIn(Integer actorId, Integer storeId) {
        return storeDao.getWhichFilmTheActorWereInvolvedIn(actorId, storeId);
    }


    /**
     * 借出
     * @param rental 包括customerId,rentalDate,inventoryId,staffId,storeId
     * @return 成功与否信息
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public String getCustomerRental(Rental rental) {
        //插入之前先查询 确认这个库存id是否尚在库中
        //msg有3种结果 返回null则表示这家店没有这个影片.有的话只会返回'未借出'和'已借出'
        String msg = storeDao.inventoryIsExit(rental.getInventoryId(), rental.getStoreId());
        if (msg==null){
            return "此店铺没有此影片";
        }
        if ("已借出".equals(msg)){
            return "影片以借出";
        }
        if ("未借出".equals(msg)){
            Integer affect = storeDao.getCustomerRental(rental);
            if (affect==1){
                return "成功";
            }
            return "失败";
        }
        return "未知错误";
    }
}

    /**
     Rental(rentalId=null,
     inventoryId=5,
     filmId=null,
     rentalDuration=null,
     rentalRate=null,
     replacementCost=null,
     filmTitle=null,
     customerId=1,
     rentalDate=2021-04-28 22:29:57,
     returnDate=null,
     staffId=4,
     returnStaffId=null,
     storeId=2,
     amount=null)
     */
